#ifndef MENUMANAGER_H
#define MENUMANAGER_H

#include <QObject>
#include <QString>
#include <QStringList>
#include <QUuid>
#include <QDateTime>
#include <QHash>
#include <QMutex>
#include <memory>
#include "../data/models.h"
#include "../data/datamanager.h"
#include "../utils/errorhandler.h"

/**
 * @brief 菜单管理器
 * 
 * 负责菜品信息管理、库存控制、分类管理等功能
 * 提供菜品CRUD操作、库存预警、销量统计等服务
 */

namespace RestaurantSystem {

/**
 * @brief 菜品操作结果枚举
 */
enum class MenuOperationResult {
    SUCCESS = 0,              // 操作成功
    ITEM_NOT_FOUND,          // 菜品不存在
    INVALID_DATA,            // 数据无效
    DUPLICATE_NAME,          // 菜品名称重复
    INSUFFICIENT_STOCK,      // 库存不足
    CATEGORY_NOT_FOUND,      // 分类不存在
    SYSTEM_ERROR             // 系统错误
};

/**
 * @brief 库存预警信息
 */
struct StockAlert {
    QString menuItemId;
    QString menuItemName;
    int currentStock;
    int threshold;
    
    StockAlert() : currentStock(0), threshold(0) {}
    StockAlert(const QString& id, const QString& name, int stock, int thresh)
        : menuItemId(id), menuItemName(name), currentStock(stock), threshold(thresh) {}
    
    bool isLowStock() const { return currentStock <= threshold; }
};

/**
 * @brief 菜品搜索条件
 */
struct MenuSearchCriteria {
    QString keyword;          // 关键词搜索
    QString category;         // 分类过滤
    double minPrice = -1;     // 最低价格
    double maxPrice = -1;     // 最高价格
    bool inStockOnly = false; // 仅显示有库存的
    
    MenuSearchCriteria() = default;
    
    bool hasFilters() const {
        return !keyword.isEmpty() || !category.isEmpty() || 
               minPrice >= 0 || maxPrice >= 0 || inStockOnly;
    }
};

/**
 * @brief 菜单管理器类
 */
class MenuManager : public QObject {
    Q_OBJECT
    
public:
    explicit MenuManager(QObject* parent = nullptr);
    ~MenuManager();
    
    /**
     * @brief 获取单例实例
     */
    static MenuManager& instance();
    
    /**
     * @brief 初始化菜单管理器
     * @return 初始化是否成功
     */
    bool initialize();
    
    // ========================================================================
    // 菜品管理
    // ========================================================================
    
    /**
     * @brief 获取所有菜品
     * @return 菜品列表
     */
    QList<MenuItem> getAllMenuItems();
    
    /**
     * @brief 根据ID获取菜品
     * @param id 菜品ID
     * @return 菜品信息，不存在则返回无效对象
     */
    MenuItem getMenuItemById(const QString& id);
    
    /**
     * @brief 根据分类获取菜品
     * @param category 分类名称
     * @return 菜品列表
     */
    QList<MenuItem> getMenuItemsByCategory(const QString& category);
    
    /**
     * @brief 搜索菜品
     * @param criteria 搜索条件
     * @return 符合条件的菜品列表
     */
    QList<MenuItem> searchMenuItems(const MenuSearchCriteria& criteria);
    
    /**
     * @brief 添加菜品
     * @param item 菜品信息
     * @return 操作结果
     */
    MenuOperationResult addMenuItem(const MenuItem& item);
    
    /**
     * @brief 更新菜品信息
     * @param item 菜品信息
     * @return 操作结果
     */
    MenuOperationResult updateMenuItem(const MenuItem& item);
    
    /**
     * @brief 删除菜品
     * @param id 菜品ID
     * @return 操作结果
     */
    MenuOperationResult deleteMenuItem(const QString& id);
    
    /**
     * @brief 批量更新菜品
     * @param items 菜品列表
     * @return 操作结果
     */
    MenuOperationResult batchUpdateMenuItems(const QList<MenuItem>& items);
    
    /**
     * @brief 复制菜品
     * @param sourceId 源菜品ID
     * @param newName 新菜品名称
     * @return 操作结果
     */
    MenuOperationResult duplicateMenuItem(const QString& sourceId, const QString& newName);
    
    // ========================================================================
    // 库存管理
    // ========================================================================
    
    /**
     * @brief 更新菜品库存
     * @param id 菜品ID
     * @param newStock 新库存数量
     * @return 操作结果
     */
    MenuOperationResult updateStock(const QString& id, int newStock);
    
    /**
     * @brief 增加库存
     * @param id 菜品ID
     * @param quantity 增加数量
     * @return 操作结果
     */
    MenuOperationResult increaseStock(const QString& id, int quantity);
    
    /**
     * @brief 减少库存
     * @param id 菜品ID
     * @param quantity 减少数量
     * @return 操作结果
     */
    MenuOperationResult decreaseStock(const QString& id, int quantity);
    
    /**
     * @brief 检查库存是否充足
     * @param id 菜品ID
     * @param requiredQuantity 需要数量
     * @return 是否充足
     */
    bool isStockSufficient(const QString& id, int requiredQuantity);
    
    /**
     * @brief 获取低库存菜品
     * @param threshold 库存阈值(默认5)
     * @return 低库存菜品列表
     */
    QList<StockAlert> getLowStockItems(int threshold = 5);
    
    /**
     * @brief 设置库存预警阈值
     * @param id 菜品ID
     * @param threshold 阈值
     * @return 操作是否成功
     */
    bool setStockThreshold(const QString& id, int threshold);
    
    /**
     * @brief 批量补充库存
     * @param stockUpdates 库存更新映射(菜品ID -> 补充数量)
     * @return 操作结果
     */
    MenuOperationResult batchReplenishStock(const QHash<QString, int>& stockUpdates);
    
    // ========================================================================
    // 分类管理
    // ========================================================================
    
    /**
     * @brief 获取所有分类
     * @return 分类列表
     */
    QStringList getAllCategories();
    
    /**
     * @brief 添加分类
     * @param category 分类名称
     * @return 操作是否成功
     */
    bool addCategory(const QString& category);
    
    /**
     * @brief 删除分类
     * @param category 分类名称
     * @return 操作是否成功
     */
    bool removeCategory(const QString& category);
    
    /**
     * @brief 重命名分类
     * @param oldName 原分类名
     * @param newName 新分类名
     * @return 操作是否成功
     */
    bool renameCategory(const QString& oldName, const QString& newName);
    
    /**
     * @brief 获取分类下的菜品数量
     * @param category 分类名称
     * @return 菜品数量
     */
    int getCategoryItemCount(const QString& category);
    
    /**
     * @brief 检查分类是否为空
     * @param category 分类名称
     * @return 是否为空
     */
    bool isCategoryEmpty(const QString& category);
    
    // ========================================================================
    // 销量和统计
    // ========================================================================
    
    /**
     * @brief 更新菜品销量
     * @param id 菜品ID
     * @param quantity 销售数量
     * @return 操作是否成功
     */
    bool updateSalesCount(const QString& id, int quantity);
    
    /**
     * @brief 获取热销菜品
     * @param limit 返回数量限制
     * @return 热销菜品列表(按销量排序)
     */
    QList<MenuItem> getPopularItems(int limit = 10);
    
    /**
     * @brief 获取分类销量统计
     * @return 分类销量映射
     */
    QHash<QString, int> getCategorySales();
    
    /**
     * @brief 重置所有菜品销量
     * @return 操作是否成功
     */
    bool resetAllSalesCount();
    
    // ========================================================================
    // 数据验证和辅助
    // ========================================================================
    
    /**
     * @brief 验证菜品数据
     * @param item 菜品信息
     * @return 验证结果
     */
    ValidationResult validateMenuItem(const MenuItem& item);
    
    /**
     * @brief 检查菜品名称是否重复
     * @param name 菜品名称
     * @param excludeId 排除的菜品ID(用于更新时检查)
     * @return 是否重复
     */
    bool isMenuItemNameDuplicate(const QString& name, const QString& excludeId = "");
    
    /**
     * @brief 生成唯一菜品ID（旧版本，使用UUID）
     * @return 菜品ID
     */
    static QString generateMenuItemId();
    
    /**
     * @brief 根据现有菜品列表智能生成新的菜品ID
     * @param existingItems 现有菜品列表
     * @return 新的菜品ID
     */
    QString generateSmartMenuItemId(const QList<MenuItem> &existingItems);
    
    /**
     * @brief 检查ID是否已存在
     * @param id 要检查的ID
     * @param existingItems 现有菜品列表
     * @return 是否存在
     */
    bool isIdExists(const QString &id, const QList<MenuItem> &existingItems);
    
    /**
     * @brief 获取操作结果描述
     * @param result 操作结果
     * @return 描述字符串
     */
    static QString getOperationResultMessage(MenuOperationResult result);
    
    /**
     * @brief 格式化价格显示
     * @param price 价格
     * @return 格式化后的价格字符串
     */
    static QString formatPrice(double price);

signals:
    /**
     * @brief 菜品添加信号
     * @param item 添加的菜品
     */
    void menuItemAdded(const MenuItem& item);
    
    /**
     * @brief 菜品更新信号
     * @param item 更新后的菜品
     */
    void menuItemUpdated(const MenuItem& item);
    
    /**
     * @brief 菜品删除信号
     * @param itemId 删除的菜品ID
     */
    void menuItemDeleted(const QString& itemId);
    
    /**
     * @brief 库存更新信号
     * @param itemId 菜品ID
     * @param oldStock 原库存
     * @param newStock 新库存
     */
    void stockUpdated(const QString& itemId, int oldStock, int newStock);
    
    /**
     * @brief 库存不足信号
     * @param itemId 菜品ID
     * @param currentStock 当前库存
     * @param requiredQuantity 需要数量
     */
    void stockInsufficient(const QString& itemId, int currentStock, int requiredQuantity);
    
    /**
     * @brief 低库存预警信号
     * @param alerts 预警列表
     */
    void lowStockAlert(const QList<StockAlert>& alerts);
    
    /**
     * @brief 分类变更信号
     * @param categories 更新后的分类列表
     */
    void categoriesChanged(const QStringList& categories);
    
    /**
     * @brief 销量更新信号
     * @param itemId 菜品ID
     * @param newSalesCount 新的销量
     */
    void salesCountUpdated(const QString& itemId, int newSalesCount);

public slots:
    /**
     * @brief 刷新菜单数据
     */
    void refreshMenuData();
    
    /**
     * @brief 检查库存预警
     */
    void checkStockAlerts();

private slots:
    void onStockCheckTimer();
    void onExternalFileChanged(DataType dataType, const QString& filePath);

private:
    /**
     * @brief 加载菜单数据到缓存
     * @return 操作是否成功
     */
    bool loadMenuData();
    
    /**
     * @brief 保存菜单数据
     * @return 操作是否成功
     */
    bool saveMenuData();
    
    /**
     * @brief 更新分类列表
     */
    void updateCategoriesList();
    
    /**
     * @brief 保存菜单数据（内部方法，假设调用者已持有锁）
     * @return 操作是否成功
     */
    bool saveMenuDataInternal();
    
    /**
     * @brief 检查菜品名称是否重复（内部版本，不获取锁）
     * @param name 菜品名称
     * @param excludeId 排除的菜品ID
     * @return 是否重复
     */
    bool isMenuItemNameDuplicateInternal(const QString& name, const QString& excludeId = "");
    
    /**
     * @brief 验证菜品搜索条件
     * @param item 菜品
     * @param criteria 搜索条件
     * @return 是否匹配
     */
    bool matchesSearchCriteria(const MenuItem& item, const MenuSearchCriteria& criteria);
    
    /**
     * @brief 发送库存预警
     */
    void emitStockAlertsIfNeeded();
    
    /**
     * @brief 检查库存变化并发射信号
     * @param oldStocks 旧的库存状态
     */
    void checkAndEmitStockChanges(const QHash<QString, int>& oldStocks);
    
    /**
     * @brief 检查销量变化并发射信号
     * @param oldSalesCounts 旧的销量状态
     */
    void checkAndEmitSalesChanges(const QHash<QString, int>& oldSalesCounts);
    
    /**
     * @brief 检查菜品信息变化并发射信号
     * @param oldMenuItems 旧的菜品信息状态
     */
    void checkAndEmitMenuItemChanges(const QHash<QString, MenuItem>& oldMenuItems);

private:
    static MenuManager* s_instance;
    
    DataManager* m_dataManager;
    
    // 缓存数据
    QList<MenuItem> m_menuItems;
    QStringList m_categories;
    QHash<QString, int> m_stockThresholds; // 菜品ID -> 库存阈值
    
    // 定时器
    QTimer* m_stockCheckTimer;
    
    // 线程安全
    mutable QMutex m_mutex;
    
    // 状态标识
    bool m_isInitialized;
    bool m_dataLoaded;
    
    // 默认库存阈值
    static const int DEFAULT_STOCK_THRESHOLD;
};

} // namespace RestaurantSystem

#endif // MENUMANAGER_H
